﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.Migrations;

namespace SmartSpace.Core
{
    public class CoreDbContext : DbContext
    {
        public CoreDbContext()
            : base("name=" + SmartSpace.Configuration.ConnectionStringName)
        {
            if (SmartSpace.Configuration.IsAutomaticMigrations)
            {
                Database.SetInitializer<CoreDbContext>(new MigrateDatabaseToLatestVersion<CoreDbContext, DBMC>());
            }
            else
            {
                Database.SetInitializer<CoreDbContext>(null);
            }
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Image>().ToTable("core_image");
            modelBuilder.Entity<Image>().HasKey(p => p.Id);

            modelBuilder.Entity<User>().ToTable("core_user");
            modelBuilder.Entity<User>().HasKey(p => p.Id);
            modelBuilder.Entity<User>().Property(p => p.Id).IsRequired();

            modelBuilder.Entity<UserGroup>().ToTable("core_usergroup");
            modelBuilder.Entity<UserGroup>().HasKey(p => p.Id);

            modelBuilder.Entity<UserGroupRelation>().ToTable("core_usergrouprelation");
            modelBuilder.Entity<UserGroupRelation>().HasKey(p => p.Id);

            modelBuilder.Entity<IntegrationUser>().ToTable("core_integrationuser");
            modelBuilder.Entity<IntegrationUser>().HasKey(p => p.Id);
            modelBuilder.Entity<IntegrationUser>().Property(p => p.Id).IsRequired();

            modelBuilder.Entity<Role>().ToTable("core_role");
            modelBuilder.Entity<Role>().HasKey(p => p.Id);
            modelBuilder.Entity<Role>().Property(p => p.Id).IsRequired();

            modelBuilder.Entity<UserRoleRelation>().ToTable("core_userrolerelation");
            modelBuilder.Entity<UserRoleRelation>().HasKey(p => p.Id);
            modelBuilder.Entity<UserRoleRelation>().HasRequired(p => p.Role).WithMany().HasForeignKey(p => p.RoleId);

            modelBuilder.Entity<Site>().ToTable("core_site");
            modelBuilder.Entity<Site>().HasKey(p => p.Id);
            modelBuilder.Entity<Site>().Property(p => p.Id).IsRequired();

            modelBuilder.Entity<SiteTemplate>().ToTable("core_sitetemplate");
            modelBuilder.Entity<SiteTemplate>().HasKey(p => p.Id);

            modelBuilder.Entity<SiteModuleRelation>().ToTable("core_sitemodulerelation");

            modelBuilder.Entity<Module>().ToTable("core_module");
            modelBuilder.Entity<Module>().HasKey(p => p.Id);
            modelBuilder.Entity<Module>().HasMany(p => p.Views)
                .WithRequired(p => p.Module).HasForeignKey(p => p.ModuleId);

            modelBuilder.Entity<ModuleView>().ToTable("core_moduleview");
            modelBuilder.Entity<ModuleView>().HasKey(p => p.Id);

            modelBuilder.Entity<Navigation>().ToTable("core_navigation");
            modelBuilder.Entity<Navigation>().HasKey(p => p.Id);
            modelBuilder.Entity<Navigation>()
                .HasMany(p => p.Children)
                .WithOptional()
                .HasForeignKey(p => p.ParentId);

            modelBuilder.Entity<Shortcut>().ToTable("core_shortcut");
            modelBuilder.Entity<Shortcut>().HasKey(p => p.Id);

            modelBuilder.Entity<Privilege>().ToTable("core_privilege");
            modelBuilder.Entity<Privilege>().HasKey(p => p.Id);

            modelBuilder.Entity<VirtualPage>().ToTable("core_virtualpage");
            modelBuilder.Entity<VirtualPage>().HasKey(p => p.Id);
            modelBuilder.Entity<VirtualPage>().HasRequired(p => p.Template)
                .WithMany().HasForeignKey(p => p.TemplateId);

            //modelBuilder.Entity<VirtualMenu>().ToTable("core_virtualmenu");
            //modelBuilder.Entity<VirtualMenu>().HasKey(p => p.Id);
            //modelBuilder.Entity<VirtualMenu>().HasMany(p => p.Children)
            //    .WithOptional().HasForeignKey(p => p.ParentId);

            modelBuilder.Entity<PageTemplate>().ToTable("core_pagetemplate");
            modelBuilder.Entity<PageTemplate>().HasKey(p => p.Id);

            modelBuilder.Entity<PageContent>().ToTable("core_pagecontent");
            modelBuilder.Entity<PageContent>().HasKey(p => p.Id);

            modelBuilder.Entity<AssignedPrivilege>().ToTable("core_assignedprivilege");
            modelBuilder.Entity<PageContent>().HasKey(p => p.Id);

            base.OnModelCreating(modelBuilder);
        }
    }

    internal sealed class DBMC : DbMigrationsConfiguration<CoreDbContext>
    {
        public DBMC()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }
    }

    public sealed class AutomaticDbMigrationsConfiguration<TContext> : DbMigrationsConfiguration<TContext> where TContext : System.Data.Entity.DbContext
    {
        public AutomaticDbMigrationsConfiguration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }
    }
}
